<?php

/**
 * This file is part of the Framework03 PHP framework.
 * @author Walter Tamboer
 * @package Framework03
 */

require_once 'FW/Config/Exception.php';

/**
 * The Xml configuration reader and writer.
 */
class FW_Config_Xml extends FW_Config
{
    public function __construct($filename, $section = null, $allowModifications = false)
    {
        if (empty($filename))
            throw new FW_Config_Exception('Filename is not set.');

        if (!is_file($filename))
            throw new FW_Config_Exception("File '$filename' cannot be found.");

        $config = simplexml_load_file($filename);

        if ($config === false)
            throw new FW_Config_Exception("The file '$filename' is not a (valid) XML document");

        $data = array();

        if ($section !== null)
        {
            if (!isset($config->$section))
                throw new FW_Config_Exception("Section '$section' cannot be found in $filename.");

            $data = $this->getDataFromSection($config, $section);
        }
        
        parent::__construct($data);
    }

    private function getDataFromSection(SimpleXMLElement $config, $section)
    {
        if (!$config->$section)
            throw new FW_Config_Exception("Section '$section' cannot be found");

        $element = $config->$section;

        $data = array();

        if (isset($element[ 'extends' ]))
            $data = $this->getDataFromSection($config, $element[ 'extends' ]);

        return $this->mergeArrays($data, $this->createDataArray($element));
    }

    private function createDataArray(SimpleXMLElement $element)
    {
        $data = array();

        $children = $element->children();

        foreach ($children as $child)
        {
            $key = (string) $child->getName();

            if ($key == null)
                continue;
				
			if (count($child->children()) > 0)
				$data[$key] = $this->createDataArray($child);
			else
				$data[$key] = (string) $child;
        }

        return $data;
    }
}
